package com.wzdigit.wms.raw.service.backtosap;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.wzdigit.framework.Shift;
import com.wzdigit.mes.basic.api.BasicVendorApi;
import com.wzdigit.mes.basic.dto.VendorDTO;
import com.wzdigit.wms.basic.domain.asn.AsnDtl;
import com.wzdigit.wms.basic.domain.asn.AsnHeader;
import com.wzdigit.wms.basic.domain.basic.Sku;
import com.wzdigit.wms.basic.domain.basic.Warehouse;
import com.wzdigit.wms.basic.domain.mapping.CodeMapping;
import com.wzdigit.wms.basic.domain.mid.IfPostback;
import com.wzdigit.wms.basic.domain.transfer.GdnDtl;
import com.wzdigit.wms.basic.domain.transfer.GdnHeader;
import com.wzdigit.wms.basic.enums.AsnTypeEnum;
import com.wzdigit.wms.basic.enums.GdnTypeEnum;
import com.wzdigit.wms.basic.enums.writeback.BackResultEnum;
import com.wzdigit.wms.basic.enums.writeback.OtherSystemEnum;
import com.wzdigit.wms.basic.enums.writeback.TopicEnum;
import com.wzdigit.wms.basic.mapper.core.basic.SkuMapper;
import com.wzdigit.wms.basic.mapper.core.basic.WarehouseMapper;
import com.wzdigit.wms.basic.mapper.core.mapping.CodeMappingMapper;
import com.wzdigit.wms.basic.mapper.core.order.AsnDtlGoodsMapper;
import com.wzdigit.wms.basic.service.code.CodeMappingService;
import com.wzdigit.wms.common.entity.StatusCode;
import com.wzdigit.wms.raw.client.response.gdn.delivery.DeliveryGoodsResponse;
import com.wzdigit.wms.raw.client.response.gdn.delivery.SimpleGdnDtl;
import com.wzdigit.wms.raw.service.mid.IfPostbackService;
import com.wzdigit.wms.web.service.common.wms2sap.ZDT_Reserve;
import com.wzdigit.wms.web.service.wms2sap.outstore.ZDT_071_ReqCDK;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.ibatis.annotations.Case;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import springfox.documentation.service.VendorExtension;

import java.math.BigDecimal;
import java.util.*;

/*
 * 出库单回写
 * @return
 * @author shuaic
 * @date 2021/6/18 14:54
 */
@Service
@Slf4j
public class OutStoreBackService {

    @Autowired
    IfPostbackService ifPostbackService ;

    @Autowired
    private CodeMappingService codeMappingService;

    @Autowired
    SkuMapper skuMapper ;

    @Autowired
    CodeMappingMapper codeMappingMapper ;

    @Autowired
    AsnDtlGoodsMapper asnDtlGoodsMapper;

    @Autowired
    WarehouseMapper warehouseMapper ;
    @Reference(version = "${dubbo.consumers.basic.vendor.api:1.0.0}", check = false, timeout = 300000)
    private BasicVendorApi basicVendorApi;

    /*入库单回写
     * @param header
     * @param dtlList
     * @return void
     * @author shuaic
     * @date 2021/8/5 21:44
     */
    public  void outStoreAsnWriteBack(AsnHeader header, List<AsnDtl> dtlList,String type ){
        //查询供应商
        String orderNo ="";
        String orderSort = "";
        String  vendorCode = "";
        VendorDTO vendor = basicVendorApi.getVendorById(header.getVendorId());
        if(vendor!=null||vendor.getVendorCode()!=null){
            vendorCode = vendor.getVendorCode();
        }

        //生成回写数据
        List<ZDT_071_ReqCDK>  list = new ArrayList<>();
        for(AsnDtl dtl  : dtlList){
            ZDT_071_ReqCDK record = new ZDT_071_ReqCDK();
            ZDT_Reserve RSV1 = new ZDT_Reserve();
            //转换单据类型TODO
            record.setBUDAT(DateUtil.format(new Date(),"yyyyMMdd"));
            record.setBZTP(type);//

            //外部单据直接取单号和行号
            if(AsnTypeEnum.R20.code.equals(header.getAsnType())&&header.getAsnNo().indexOf("R20") ==0 ){//自建单传源单号
                orderNo=header.getSourceNo();
                orderSort = dtl.getSourceLineNo();
              /*  record.setCKDNO(header.getSourceNo());//送货单号
                record.setCKDITEM(dtl.getSourceLineNo()); //送货单行号*/

            }else if(AsnTypeEnum.R22.code.equals(header.getAsnType())&&header.getAsnNo().indexOf("R22") ==0){//自建单
                orderNo = header.getSourceNo();
                orderSort = dtl.getSourceLineNo();

                RSV1.setRsv2(header.getAsnNo());
                record.setRSV1(RSV1);

            }else{//内部单据取来源单号和行号
                orderNo = header.getAsnNo();
                orderSort = dtl.getAsnLineNo();

            }
            record.setCKDNO(orderNo);//送货单号
            record.setCKDITEM(orderSort); //送货单行号
            record.setEBELN(dtl.getPoNo()==null?"":dtl.getPoNo());//采购订单号
            record.setEBELP(dtl.getPoLineNo()==null?"":dtl.getPoLineNo());//采购订单行号
            record.setWMSID(header.getAsnHeaderId()+"");
            record.setLIFNR(vendorCode);//供应商代码  当单据类型为标准委外领料单出库、标准委外退本厂时，此字段为必输
            record.setWERKS(header.getFactory());//工厂
            Sku sku = skuMapper.selectById(dtl.getSkuId());
            if(sku==null){
                String message = String.format("未找到ID为【%s】的SKU信息",dtl.getSkuId());
                Shift.fatal(StatusCode.BUSINESS_ERR, message);
            }
            record.setMATNR(sku.getSkuCode());//物料
            //统计数量
            BigDecimal totalQty = asnDtlGoodsMapper.selectSumQtyByDtlId(dtl.getAsnDtlId());
            if(totalQty.compareTo(BigDecimal.ZERO)==0){//0的不传
                continue;
            }
            record.setMENGE(totalQty.toString());//数量
            //查询仓库
            Warehouse warehouse = warehouseMapper.selectById(dtl.getWhsId());
            CodeMapping codeMapping = codeMappingService.selectByWhsCodeAndFactoryOrQaStatus(header.getFactory(), warehouse.getWhsCode(), dtl.getQaStatus());

            switch (header.getAsnType()){
                case "R15":
                    record.setLGORT(codeMapping.getMappingCode());//移出库存地点
                    break;
                case "R22":
                    Warehouse warehouseOut = warehouseMapper.selectById(dtl.getUdf5());
                    CodeMapping codeMappingOut = codeMappingService.selectByWhsCodeAndFactoryOrQaStatus(header.getFactory(), warehouseOut.getWhsCode(), dtl.getQaStatus());
                    record.setLGORT(codeMappingOut.getMappingCode());//移出库存地点
                    record.setUMLGO(codeMapping.getMappingCode());//移入库存地点  当单据类型为1、内销售后领料单，4、报废出库单冻结，5、不同库位调拨，9、标准委外退本厂 此字段为必输
                    break;
                case "R20":
                    record.setLGORT(codeMapping.getMappingCode());//移出库存地点
                    break;
                default:
                    record.setLGORT(dtl.getUdf5());//移出库存地点
                    record.setUMLGO(codeMapping.getMappingCode());//移入库存地点  当单据类型为1、内销售后领料单，4、报废出库单冻结，5、不同库位调拨，9、标准委外退本厂 此字段为必输
                    break;

            }

            list.add(record);
        }
        String jsonString = JSON.toJSONString(list);

        //插入数据到待回传数据表
        IfPostback ifPostback = new IfPostback();
        ifPostback.setPostbackNo(orderNo);
        ifPostback.setDestSystem(OtherSystemEnum.SYSYTEM_SAP.getEnumName());
        ifPostback.setPostbackTopic(TopicEnum.TOPIC_SAP_OUT_STORE.getEnumName());
        ifPostback.setPostbackContent(jsonString);
        ifPostback.setPostbackResult(BackResultEnum.DEFAULT_STATE.getCode());
        ifPostback.setCreateTime(new Date());
        ifPostback.setDestSystem(OtherSystemEnum.SYSYTEM_SAP.getEnumName());
        try {
            ifPostbackService.addOne(ifPostback);//
        } catch (Exception e) {
            e.printStackTrace();
            Shift.fatal(StatusCode.SERVER_MODIFY_ERROR);
        }

    }


    /*  出库单同步回写
     * @param header 表头
     * @param dtl 明细
     * @return boolean
     * @author shuaic
     * @date 2021/6/18 9:57
     */
    public  void outStoreGdnWriteBack(GdnHeader header, List<GdnDtl> dtlList ){
        //查询供应商
        String  vendorCode = "";
        if(header.getConsigneeId()!=null){
            VendorDTO vendor = basicVendorApi.getVendorById(header.getConsigneeId().intValue());
            if(vendor!=null||vendor.getVendorCode()!=null){
                vendorCode = vendor.getVendorCode();
            }
        }


        //生成回写数据
        String type = "";
        //转换单据类型
        switch (header.getGdnType()){
            case "D12": //标准委外退本厂
                type = "9";
                break;
            case "R17": //内销售后
                type = "1";
                break;
            case "R18": //申购
                type = "2";
                break;
            default:
                break;
        }

        List<ZDT_071_ReqCDK>  list = new ArrayList<>();
        for(GdnDtl dtl  : dtlList){
            ZDT_071_ReqCDK record = new ZDT_071_ReqCDK();
            //转换单据类型TODO
            record.setBZTP(type);//1：内销售后领料单；D14
                                    /*2：申购出库单：D15
                                    3:交货出库单
                                    4、报废出库单冻结
                                    4.1 报废单出库单过账 D16
                                    5、不同库位调拨
                                    6、工厂间调拨
                                    7、在途调拨
                                    8、标准委外领料出库D12
                                    9、标准委外退本厂*/
            //TODO
            record.setCKDNO(header.getGdnNo());//送货单号
            record.setCKDITEM(dtl.getSourceShipNoticeItem()+""); //送货单行号
            record.setEBELN(dtl.getPoNo());//采购订单号
            record.setEBELP(dtl.getPoLineNo());//采购订单行号
            // record.setLIFNR();//供应商代码  当单据类型为标准委外领料单出库、标准委外退本厂时，此字段为必输
            record.setWERKS(header.getFactory());//工厂
            Sku sku = skuMapper.selectById(dtl.getSkuId());
            if(sku==null){
                String message = String.format("未找到ID为【%s】的SKU信息",dtl.getSkuId());
                Shift.fatal(StatusCode.BUSINESS_ERR, message);
            }
            record.setMATNR(sku.getSkuCode());//物料

            record.setMENGE(dtl.getOrderQty()+"");//数量
            //查询仓库
            Warehouse warehouse = warehouseMapper.selectById(dtl.getWhsId());
            CodeMapping codeMapping = codeMappingService.selectByWhsCodeAndFactoryOrQaStatus(header.getFactory(), warehouse.getWhsCode(), dtl.getQaStatus());
            record.setLGORT(codeMapping.getMappingCode());//移出库存地点
            // record.setUMLGO();//移入库存地点  当单据类型为1、内销售后领料单，4、报废出库单冻结，5、不同库位调拨，9、标准委外退本厂 此字段为必输

            list.add(record);
        }
        String jsonString = JSON.toJSONString(list);

        //插入数据到待回传数据表
        IfPostback ifPostback = new IfPostback();
        ifPostback.setDestSystem(OtherSystemEnum.SYSYTEM_SAP.getEnumName());
        ifPostback.setPostbackNo(header.getGdnNo());
        ifPostback.setPostbackTopic(TopicEnum.TOPIC_SAP_OUT_STORE.getEnumName());
        ifPostback.setPostbackContent(jsonString);
        ifPostback.setPostbackResult(BackResultEnum.DEFAULT_STATE.getCode());
        ifPostback.setCreateTime(new Date());
        ifPostback.setDestSystem(OtherSystemEnum.SYSYTEM_SAP.getEnumName());
        try {
            ifPostbackService.addOne(ifPostback);//保存
        } catch (Exception e) {
            e.printStackTrace();
            Shift.fatal(StatusCode.SERVER_MODIFY_ERROR);
        }

    }

    /**
     * @param header 出库单主表
     * @param dtlCollectMap 出库单明细分组
     * @param goodsCollectMap  出库单明细SN
     * @return void
     * @author shuaic
     * @date 2021/8/10 23:08
     */
    public void gdnWriteBackToSap(GdnHeader header, Map<BigDecimal, List<SimpleGdnDtl>> dtlCollectMap, Map<BigDecimal, List<DeliveryGoodsResponse>> goodsCollectMap,String type) {
        //查询供应商
        String  vendorCode = "";
        if(header.getConsigneeId()!=null){
            VendorDTO vendor = basicVendorApi.getVendorById(header.getConsigneeId().intValue());
            if(vendor!=null||vendor.getVendorCode()!=null){
                vendorCode = vendor.getVendorCode();
            }
        }

        //回写数据集合
        List<ZDT_071_ReqCDK>  list = new ArrayList<>();
        for (Map.Entry<BigDecimal, List<SimpleGdnDtl>> entry : dtlCollectMap.entrySet()) {
            BigDecimal key = entry.getKey();//明细ID
            SimpleGdnDtl dtl = entry.getValue().get(0);//出库单明细
            //获取明细交货数量
            ZDT_071_ReqCDK record = new ZDT_071_ReqCDK();
            //转换单据类型TODO
            record.setBZTP(type);//1：内销售后领料单；D14
                                /*2：申购出库单：D15
                                3:交货出库单
                                4、报废出库单冻结
                                4.1 报废单出库单过账 D16
                                5、不同库位调拨
                                6、工厂间调拨
                                7、在途调拨
                                8、标准委外领料出库D12
                                9、标准委外退本厂*/

            //随便给个ID
            record.setWMSID(UUID.randomUUID().toString().replace("-",""));
            if(header.getGdnType().equals(GdnTypeEnum.D16.code)){//报废出库单 取其他单号
                record.setCKDNO(header.getSourceShipNotice());//送货单号
                record.setCKDITEM(dtl.getSourceShipNoticeItem()+""); //送货单行号
            }else{
                record.setCKDNO(header.getGdnNo());//送货单号
                record.setCKDITEM(dtl.getSourceShipNoticeItem()+""); //送货单行号
            }

            record.setEBELN(dtl.getPoNo());//采购订单号
            record.setEBELP(dtl.getPoLineNo());//采购订单行号
            record.setLIFNR(vendorCode);//供应商代码  当单据类型为标准委外领料单出库、标准委外退本厂时，此字段为必输
            record.setWERKS(header.getFactory());//工厂
            Sku sku = skuMapper.selectById(dtl.getSkuId());
            if(sku==null){
                String message = String.format("未找到ID为【%s】的SKU信息",dtl.getSkuId());
                Shift.fatal(StatusCode.BUSINESS_ERR, message);
            }
            record.setMATNR(sku.getSkuCode());//物料
            List<DeliveryGoodsResponse> goodsList = goodsCollectMap.get(key);
            //计算数量
            BigDecimal totalQty = goodsList.stream().map(DeliveryGoodsResponse::getQty)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            record.setMENGE(totalQty.toString());//数量
            //查询仓库
            Warehouse warehouse = warehouseMapper.selectById(dtl.getWhsId());
            CodeMapping codeMapping = codeMappingService.selectByWhsCodeAndFactoryOrQaStatus(header.getFactory(), warehouse.getWhsCode(), dtl.getQaStatus());
            //这个地方后面改
            switch (header.getGdnType()){
                case "D25":
                    record.setUMLGO(dtl.getUdf5()==null?"":dtl.getUdf5());//移入库位
                    record.setLGORT(codeMapping.getMappingCode());//移出库存地点
                    break;

                default:
                    record.setUMLGO(dtl.getUdf5()==null?"":dtl.getUdf5());//移入库位
                    record.setLGORT(codeMapping.getMappingCode());//移出库存地点
                    break;
            }
            record.setBUDAT(DateUtil.format(new Date(),"yyyyMMdd"));
            // record.setUMLGO();//移入库存地点  当单据类型为1、内销售后领料单，4、报废出库单冻结，5、不同库位调拨，9、标准委外退本厂 此字段为必输
            list.add(record);


        }

        String jsonString = JSON.toJSONString(list);

        //插入数据到待回传数据表
        IfPostback ifPostback = new IfPostback();
        ifPostback.setDestSystem(OtherSystemEnum.SYSYTEM_SAP.getEnumName());
        ifPostback.setPostbackNo(header.getGdnNo());
        ifPostback.setPostbackTopic(TopicEnum.TOPIC_SAP_OUT_STORE.getEnumName());
        ifPostback.setPostbackContent(jsonString);
        ifPostback.setPostbackResult(BackResultEnum.DEFAULT_STATE.getCode());
        ifPostback.setCreateTime(new Date());
        ifPostback.setDestSystem(OtherSystemEnum.SYSYTEM_SAP.getEnumName());
        try {
            ifPostbackService.addOne(ifPostback);//保存
        } catch (Exception e) {
            e.printStackTrace();
            Shift.fatal(StatusCode.SERVER_MODIFY_ERROR);
        }
    }
}
